<?php

namespace app;

use extend\DataSet;
use extend\DefaultValue;
use extend\Table;
use extend\Upload;
use extend\Verify;
use think\facade\Db;

class QEdit
{


    static $table;

    static function init()
    {
        $authCheck = self::checkAuth();
        if ($authCheck !== true) {
            return $authCheck;
        }

        $data = input();

        self::$table = isset($data['table']) && $data['table'] ? $data['table'] : '';

        $action = $data['qeditor'];

        if (method_exists(QEdit::class, $action)) {
            return call_user_func_array([QEdit::class, $action], [$data]);
        } else {
            return json('', 0, '');
        }
    }

    static function checkAuth()
    {
        if (!s('qadmin') && !is_admin()) {
            return json('未登录或无权限访问', 0);
        }
        return true;
    }


    /**
     * 用户自定义配置
     * @auth false
     * @param $data
     */
    static function form($data)
    {
        $authCheck = self::checkAuth();
        if ($authCheck !== true) {
            return $authCheck;
        }

        $mode = input('mode');

        $config = Table::getConfig(self::$table, $mode);

        if (!$config) {
            return json([], 0);
        }

        $pk_value = isset($data[$config['pk']]) && $data[$config['pk']] ? $data[$config['pk']] : ((int)($data['pk_val'] ?? ''));

        //是否为编辑数据
        if ($config && $pk_value) {
            $relations = [];


            $sfields = array_unique(array_merge($config['edit_fields'], array_keys($config['condition_fields'])));

            //先找出数据
            $data = db()->where($config['pk'], $pk_value)->getOne($config['table_name'], $sfields);

            //条件编辑
            $editable = true;

            if ($data && $config['condition_fields']) {

                foreach ($config['condition_fields'] as $field_key => $condition_str) {
                    $editable=Table::parseConditionValue($condition_str,$field_key,array_merge($data,input()??[]));
                    if(!$editable){
                        break;
                    }
                }

                if (!$editable) {
                    return json([], 0, '无编辑权限');
                }
            }
            if ($editable && $data) {

                foreach ($config['field_options'] as $field => $option) {
                    //数据处理
//                    p($field,$config['struct']);
                    if (!in_array($field, array_keys($config['struct']))) continue;

                    if (isset($option['filter']) && $option['filter'] && !in_array($option['filter'], ['请选择', ' '])) {
                        $data[$field] = call_user_func_array([DataSet::class, $option['filter']], [$data[$field], false, $option]);
                    }

                    //处理关联显示数据
                    if ($option['type'] == 'relation' && $option['option_value'] && $data[$field]) {

                        //core_user|id,nickname,mobile|nickname,mobile|mobile,nickname|id
                        list($re_table, $fields, $show_field, $search_fields, $pk) = explode('|', $option['option_value']);

                        if (!$pk) {
                            return json('', 0, '字段【' . $field . '】配置错误');
                        }
                        $fields = array_filter(explode(',', $fields));
                        $show_field = array_filter(explode(',', $show_field));

                        $relation_data = db()->where($pk, $data[$field])->getOne($re_table, $fields);

                        if ($relation_data) {
                            $title = '';

                            foreach ($show_field as $f) {
                                $title .= $relation_data[$f] . '  -  ';
                            }

                            $relations[$field] = rtrim($title, '  -  ');
                        }
                    }

                }

                $config['relation'] = $relations;
                $config['data'] = $data;
            }
        }

        unset($config['default_value_fields'], $config['list_fields']);

        return $config ? json($config) : json([]);
    }

    /**
     * 文件上传
     * @auth false
     * @param $data
     * @return string
     */
    static function upload($data)
    {

        $upload = new Upload(); 

        $is_image = isset($data['type']) && in_array($data['type'], ['image', 'images']);

        $dir = $is_image ? 'images' : 'files';

        $res = $is_image ?
            $upload->uploadImage($dir) :
            $upload->upload($dir);

        if ($res) {
            return json($res);
        } else {
            return json('上传失败:' . $upload->getError(), 0);
        }
    }


    /**
     * 保存操作
     * @auth false
     * @param $data
     * @return string
     */
    static function save($data)
    {

        $table = $data['qeditor_table'] ?? '';

        $mode = $data['qeditor_mode'] ?? '';

        if (!$table) {
            return json('参数错误');
        }

        $config = Table::getConfig($table, $mode);

        //检测必填
        $require_fields = $config['require_fields'] ?? [];

        $insert = [];


        if (!$config['can_create']) {
            //不允许新增
            if ($config['pk'] && (!isset($data[$config['pk']]) || !$data[$config['pk']])) {
                return json('不允许新增数据', 0);
            }
        }

        //根据规则调用
        foreach ($config['field_options'] as $field => $option) {
            //必填验证
            if ($require_fields && in_array($field, $require_fields) && (!isset($data[$field]) || !$data[$field])) {
                return json($option['placeholder'] ?: '请输入' . $config['field_titles'][$field], 0);
            }
            //规则校验

            if ($option['verify'] && $data[$field]) {

                $calls = array_filter(preg_split("/\r\n/", $option['verify']));

                if ($calls) {

                    foreach ($calls as $call) {
                        $call = array_filter(explode('|', $call));

                        if (method_exists(Verify::class, $call[0])) {

                            if (!call_user_func_array([Verify::class, $call[0]], [$data[$field], $call[1] ?? []])) {
                                return json($option['placeholder'] ?? $config['field_titles'][$field] . '输入不合法', 0);
                            }

                        } else {
                            if (!call_user_func_array([Verify::class, 'regex'], [$call[0], $data[$field]])) {
                                return json($option['placeholder'] ?? $config['field_titles'][$field] . '输入不合法', 0);
                            }
                        }
                    }
                }

            }
            //数据添加

            if (isset($data[$field])) {
                $insert[$field] = method_exists(DataSet::class, $option['filter']) ?
                    call_user_func_array(
                        [DataSet::class, $option['filter']],
                        [$data[$field], true, $option]
                    ) : $data[$field];
            }

        }


        //默认值回调
        if ($config['default_value_fields']) {

            foreach ($config['default_value_fields'] as $f => $default_value) {

                if ($default_value && (!isset($insert[$f]) || !$insert[$f])) {
                    //$default_value callback:time or  123456
                    $arr = explode('|', $default_value);

                    if (strpos($default_value, 'callback') !== false) {
                        //是回调函数

                        if (isset($arr[1])) {

                            if (method_exists(DefaultValue::class, $arr[1])) {

                                if (isset($arr[2]) || !isset($insert[$f]) || !$insert[$f]) {
                                    //是不是实时编辑每次更新
                                    try {
                                        $insert[$f] = call_user_func_array([DefaultValue::class, $arr[1]], [$data]);
                                    } catch (\Exception $e) {
                                        return json($e->getMessage(), 0);
                                    }
                                }

                            } elseif (is_callable($arr[1])) {

                                if (isset($arr[2]) || !isset($insert[$f]) || !$insert[$f]) {
                                    try {
                                        $insert[$f] = call_user_func($arr[1], $data);
                                    } catch (\Exception $e) {
                                        return json($e->getMessage(), 0);
                                    }
                                }


                            } else {
                                return json($f . '字段配置错误', 0);
                            }

                        } else {

                            if (isset($arr[1]) || !isset($insert[$f]) || !$insert[$f]) {
                                $insert[$f] = $default_value;
                            }

                        }

                    }
                }
            }
        }


        //判断是否为新增
        if ($config['pk'] && isset($data[$config['pk']]) && $data[$config['pk']] &&
            $find = db()->where($config['pk'], $data[$config['pk']])->getOne($config['table_name'])
        ) {
            $is_update = true;
        } else {
            $is_update = false;
            unset($insert[$config['pk']]);
        }


        if ($is_update) {
            $res = db()->where($config['pk'], $data[$config['pk']])->update($config['table_name'], $insert);
            $id = $data[$config['pk']];
        } else {
            $res = db()->insert($config['table_name'], $insert);
            $id = db()->getInsertId();
        }


        return $res ? json($id, 200, '操作成功') : json('操作失败', 0);
    }


    static function relation($data)
    {
        //当前操作表
        $table = $data['qeditor_table'] ?? '';
        //关联的字段
        $field = $data['qeditor_field'] ?? '';
        //查询关键字
        $key = $data['qeditor_keyword'] ?? '';

        $mode=$data['qeditor_mode'] ?? '';

        $config = Table::getConfig($table, $mode);

        if (!$field || !$config || !isset($config['field_options'][$field]) || $config['field_options'][$field]['type'] != 'relation') {
            return json('', 0);
        }
        $option = $config['field_options'][$field];
        //关联表     查询字段      显示字段   搜索字段         最终值字段
        //core_user|id,nickname|nickname|mobile,nickname|id
        list($re_table, $fields, $show_field, $search_fields, $pk) = explode('|', $option['option_value']);

        if (!$pk) {
            return json('', 0, '字段【' . $field . '】配置错误');
        }

        $search_fields = array_filter(explode(',', $search_fields));
        $fields = array_filter(explode(',', $fields));
        $show_field = array_filter(explode(',', $show_field));
        
        $DB = db();

        if ($search_fields) {
            foreach ($search_fields as $f) {
                $DB->where($f, '%' . $key . '%', 'like', 'or');
            }
        }
        $res = $DB->get($re_table, 15, $fields);


        $relation_fields_map = Table::getFieldMap($re_table, array_merge($show_field, $search_fields));
        //显示字段的map

        $data = [
            'config' => [
                'field_map' => $relation_fields_map,
                'search_fields' => $search_fields,
                'val_field' => $pk,
                'fields' => $fields,
                'show_field' => $show_field,
            ],
            'data' => $res
        ];

        return json($data);


    }

    static function area($data)
    {

        $position = (isset($data['position']) && trim($data['position']) != '') ? $data['position'] : 0;

        if ($position == 0) {
            $parents = db()->where('pcode', 0)->get(AREA_DATA_TABLE);
            $res = ['self' => [], 'parents' => $parents, 'sons' => $parents, 'level' => []];
            return json($res);
        }

        $data = Table::getAreas($position);

        return json($data);
    }

    /**
     * 区域子区域
     * @auth false
     * @param $data
     * @return string
     * @throws \Exception
     */
    static function sonAreas($data)
    {
        $area = $data['area'];

        $result = [];
        $result = Table::getSonRelations($area, $result);

        return json($result);
    }


    static function areaValue($data){

        if(!$data['area']){
            return  json([]);
        }

        is_string($data['area']) && $data['area'] && $data['area']=[$data['area']];

        $areas=array_unique($data['area']);

        $in='(\''.implode('\',\'',$areas).'\')';

        $areas = db()->where('code IN '.$in)->get(AREA_DATA_TABLE, null, ['code','name']);

        return json($areas);

    }


    static function miniValue($data)
    {

        if(!$data['value']){
            return json('');
        }
        switch ($data['type']) {
            case 'area':
                $data['value']=is_array($data['value'])?implode(',',$data['value']):$data['value'];
                $areas = db()->where('code IN (' . $data['value'] . ')')->get(AREA_DATA_TABLE, 1, ['GROUP_CONCAT(name) as name']);

                if ($areas) {
                    return json($areas[0]['name'], 200, '');
                }
                break;
        }
    }

}